package com.asiainfo.dacp.datastash.worker.executor.adapter.datax;

import com.asiainfo.dacp.datastash.worker.executor.adapter.datax.translate.JdbcTranslate;
import com.asiainfo.dacp.datastash.worker.executor.adapter.datax.utils.Configuration;
import com.asiainfo.dacp.util.StringUtils;
import net.sourceforge.argparse4j.ArgumentParsers;
import net.sourceforge.argparse4j.inf.ArgumentParser;
import net.sourceforge.argparse4j.inf.ArgumentParserException;
import net.sourceforge.argparse4j.inf.Namespace;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Map;
import java.util.List;
import java.util.HashMap;
import java.util.ArrayList;
import org.apache.commons.exec.CommandLine;
import com.google.common.base.Joiner;

import org.apache.commons.exec.DefaultExecutor;
import org.apache.commons.exec.Executor;
import com.asiainfo.dacp.datastash.common.WorkerExecutor;
import com.asiainfo.dacp.datastash.worker.executor.adapter.datax.model.Constant;
import com.asiainfo.dacp.datastash.worker.executor.adapter.datax.utils.ConfigUtils;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;

public class DpWorkerExecutor  implements WorkerExecutor{
	private static final Logger LOG = LoggerFactory.getLogger(DpWorkerExecutor.class);

	private static JdbcTranslate JdbcTranslate;
	static
	{
		ApplicationContext context = new FileSystemXmlApplicationContext(new String[]{"classpath:conf/spring/*.xml","conf/spring/*.xml"});
		JdbcTranslate= context.getBean(JdbcTranslate.class);

	}
	private String dsName="";
	private String task="";
	private Configuration configuration;
	public void argumentParser(String[] args){
		ArgumentParser parser = ArgumentParsers.newArgumentParser("datax-worker", true);
		parser.addArgument("p").metavar("JsonPara").required(true);
		try{
			Namespace res  = parser.parseArgs(args);
			String jsonp = res.getString("p");
			configuration = Configuration.from(jsonp);
			LOG.info("\n入参 : {}" , configuration.beautify());
		} catch (ArgumentParserException e) {
			parser.handleError(e);
			System.exit(-1);
		} catch (Exception e){
			LOG.error("获取入参失败 .", e);
			System.exit(-1);
		}
	}
	public  int execute(final String[] args) {
		try {
			String path = ConfigUtils.getCfg(Constant.DP_EXECUTE_PATH);
			LOG.info("DP程序执行脚本路径:［{}］.", path);
			argumentParser(args);
			Map<String, Object> data = new HashMap<String, Object>();
			String dpTemplate = DpTranslater.buildTemplate("dp");
			String batchNo = (String) configuration.get("batchNo");
			String taskProcId = (String) configuration.get("taskProcId");
			String unitid = configuration.getString(Constant.DATAX_ENTRY_PARAM_UNITID);
			List<Map> taskSteps = (List<Map>) configuration.get("taskSteps");
			List<Map> taskContent = (List<Map>) configuration.get("taskContent");
			reFormatSteps(taskSteps);
			data.put("batchNo", batchNo);
			data.put("taskProcId", taskProcId);
			data.put("taskSteps", taskSteps);
			data.put("taskContent",parseTaskContent(taskContent));
			data.put("dsName",dsName);
			data.put("task",task);
			data.put("dbs",JdbcTranslate.findAll());
			data.put("vfs",JdbcTranslate.findAllFtp());
			String dpJson = StringUtils.variableSubstitution(dpTemplate, data);
			dpJson=StringUtils.variableSubstitution(dpJson, data);
			String filePath = DataxWorkerExecutor.genFile(unitid, dpJson,".json");
			String joinedCommand = Joiner.on(' ').join(new String[]{path, " -p ", filePath," -t ",batchNo});
			LOG.info("程序执行［{}］.", joinedCommand);
			CommandLine cl = CommandLine.parse(joinedCommand);
			Executor exec = new DefaultExecutor();
			return exec.execute(cl);
		}catch (Exception e){
			e.printStackTrace();
			return -1;
		}

	}
	private void reFormatSteps(List<Map> taskSteps){
		List<String> stepIds=new ArrayList<String>();
		for(Map step:taskSteps){
			stepIds.add((String)step.get("stepIdx"));
		}
		for(Map step:taskSteps){
			List<String> nextStepsIds=(List<String>)step.get("nextStepIdxs");
			List<String> newNextIds=new ArrayList<String>();
			for(String nextStepId:nextStepsIds){
				if(!stepIds.contains(nextStepId)){
					nextStepId="-1";
				}
				newNextIds.add(nextStepId);
			}
			step.put("nextStepIdxs",newNextIds);
		}
	}
	private String parseTaskContent(List<Map> taskContent){
		StringBuffer sb=new StringBuffer();
		if(taskContent!=null) {
			for (Map content : taskContent) {
				dsName="${"+(String)content.get("dsName")+"}";
				task+=(String)content.get("content")+";";
				sb.append(dsName).append(content.get("content")).append(";");
			}
		}
		return sb.toString();
	}
}
